package com.turing.common.util;

import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SetterMethodReflect {

    private Log logger = LogFactory.getLog(SetterMethodReflect.class);

    private Object desc;

    public Hashtable<String, Method> getSetMethods() {
        return setMethods;
    }

    /**
     * 存放set方法
     */
    private Hashtable<String, Method> setMethods = null;


    public SetterMethodReflect(Object desc) {
        this.desc = desc;
    }

    public void init(Object desc) {
        this.desc = desc;
    }


    public void initSetterMethods() {
        setMethods = new Hashtable<String, Method>();
        // 获取所有方法,包括父类方法
        Class clazz = null;
        for (clazz = desc.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
            Method[] methods = clazz.getDeclaredMethods();
            // 定义正则表达式，从方法中过滤出getter / setter 函数.
            String ss = "set(\\w+)";
            Pattern setM = Pattern.compile(ss);
            // 把方法中的"set" 或者 "get" 去掉
            String rapl = "$1";
            String param;
            for (int i = 0; i < methods.length; ++i) {
                Method m = methods[i];
                String methodName = m.getName();
                if (Pattern.matches(ss, methodName)) {
                    param = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
                    setMethods.put(param, m);
                } else {
                    // System.out.println(methodName + " 不是getter,setter方法！");
                }
            }
        }
    }


    private Method getInvokeMethod(String property) {
        initSetterMethods();
        if (setMethods == null || setMethods.size() <= 0) {
            logger.warn(String.format(" Setter methods not initialized or NO Setter methods in class %s", desc.getClass()));
            return null;
        }
        return setMethods.get(property.toLowerCase());
    }

    public void invokeSetterMethod(String property, Object value) {
        Method setterMethod = getInvokeMethod(property);
        try {
            setterMethod.setAccessible(true);
            setterMethod.invoke(desc, value);
        }
//        catch ( IllegalAccessException e ) {
//            e.printStackTrace();
//        } catch ( InvocationTargetException e ) {
//            e.printStackTrace();
//        }
        catch (Exception e) {
            logger.error("property " + property + " error!");
            e.printStackTrace();
        } finally {
        }
    }

}
